package com.vrv.app.cyberspace.modules.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.vrv.app.cyberspace.common.ddio.ApiV2Service;
import com.vrv.app.cyberspace.common.ddio.DDIORunnable;
import com.vrv.app.cyberspace.common.ddio.TemplateMessage;
import com.vrv.app.cyberspace.common.utils.HttpContextUtils;
import com.vrv.app.cyberspace.common.utils.JSONResult;
import com.vrv.app.cyberspace.config.WXBSystemConfig;
import com.vrv.app.cyberspace.modules.sys.entity.*;
import com.vrv.app.cyberspace.modules.sys.mapper.*;
import com.vrv.app.cyberspace.modules.sys.service.IRiskApprovalTableService;
import com.vrv.app.cyberspace.modules.sys.service.IRiskManageTableService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.vrv.app.cyberspace.common.utils.JSONResult.renderError;
import static com.vrv.app.cyberspace.common.utils.JSONResult.renderSuccess;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author sm
 * @since 2018-01-18
 */
@SuppressWarnings({"SpringJavaInjectionPointsAutowiringInspection", "Duplicates"})
@Service
@Transactional
public class RiskManageTableServiceImpl extends ServiceImpl<RiskManageTableMapper, RiskManageTable> implements IRiskManageTableService {
    Logger logger = LoggerFactory.getLogger(RiskTableServiceImpl.class);
    private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    @Autowired
    private RiskManageTableMapper riskManageTableMapper;
    @Autowired
    private RoleTableMapper roleTableMapper;
    @Autowired
    private BaseTableMapper baseTableMapper;
    @Autowired
    private UserTableMapper userTableMapper;
    @Autowired
    private InfrastructureInformationTableMapper infrastructureInformationTableMapper;
    @Autowired
    private RiskTypeTableMapper riskTypeTableMapper;
    @Autowired
    private AttachmentTableMapper attachmentTableMapper;
    @Autowired
    private IndustryTableMapper industryTableMapper;
    @Autowired
    private RegionTableMapper regionTableMapper;
    @Autowired
    private RiskApprovalTableMapper riskApprovalTableMapper;
    @Autowired
    private RiskFeedbackTableMapper riskFeedbackTableMapper;
    @Autowired
    private IRiskApprovalTableService riskApprovalTableService;
    @Autowired
    private ApiV2Service apiV2Service;
    private ExecutorService executorService = Executors.newSingleThreadExecutor();
    @Autowired
    private WXBSystemConfig wxbSystemConfig;

    @Override
    public JSONResult addToRiskManage(Integer id, RiskManageTable rmt, String infrastructure_information, String advice) {
        UserTable userTable = (UserTable) HttpContextUtils.getHttpServletRequest().getSession().getAttribute("user");
        RoleTable roleTable = roleTableMapper.selectById(userTable.getRoleID());
        BaseTable baseTable = baseTableMapper.selectById(id);
        UserTable approvalUser = userTableMapper.selectById(rmt.getApprovalUserID());
        RoleTable approvalUserRole = roleTableMapper.selectById(approvalUser.getRoleID());
        if (!roleTable.getRoleRank().equals("2")) {
            if (approvalUserRole.getRoleRank().equals("6")) {
                return renderError("操作被禁止，只有值班员才能进行研判！");
            }
        }
        if (baseTable == null) {
            return renderError("操作被禁止，此条记录不存在！");
        }
        if (baseTable.getIsRiskManage() == 1) {
            return renderError("操作被禁止，此条记录已进行过风险通知！");
        }
        baseTable.setIsRiskManage(1);
        baseTable.updateById();
        rmt.setBaseID(id);
        rmt.setReportUserID(baseTable.getCreateUserID());
        rmt.setStatus(2);
        rmt.setCreateUserID(userTable.getLinkdoodID());
        rmt.setCreateUserID(userTable.getLinkdoodID());
        List<InfrastructureInformationTable> iits = JSONArray.parseArray(infrastructure_information, InfrastructureInformationTable.class);
        List<Integer> infrastructureIDs = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(iits)) {
            for (InfrastructureInformationTable iit :
                    iits) {
                infrastructureInformationTableMapper.insert(iit);
                infrastructureIDs.add(iit.getId());
            }
        }
        rmt.setInfrastructureIDs(StringUtils.join(infrastructureIDs, ","));
        Date now = new Date();
        rmt.setCreateTime(now);
        rmt.setUpdateTime(now);
        List<Integer> attIDs = new ArrayList<>();
        if (StringUtils.isNotEmpty(rmt.getEnclosure())) {
            try {
                JSONArray upLoadFiles = JSONArray.parseArray(rmt.getEnclosure());
                for (Object upLoadFile :
                        upLoadFiles) {
                    AttachmentTable attachmentTable = new AttachmentTable();
                    attachmentTable.setName(upLoadFile.toString().substring(upLoadFile.toString().lastIndexOf("/") + 1));
                    attachmentTable.setUrl(upLoadFile.toString());
                    attachmentTable.insert();
                    attIDs.add(attachmentTable.getId());
                }
            } catch (Exception e) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return renderError("附件参数格式异常！");
            }
            rmt.setEnclosure(StringUtils.join(attIDs, ","));
        }
        rmt.insert();
        //如果请示人为专家状态则为2专家研判，否则为1请示领导
        RiskApprovalTable rat = new RiskApprovalTable();
        rat.setBaseID(rmt.getBaseID());
        rat.setUserID(userTable.getLinkdoodID());
        rat.setAdvice(advice);
        if (approvalUserRole.getRoleRank().equals("6")) {
            rat.setApprovalStatue(2);
        } else {
            rat.setApprovalStatue(1);
        }
        rat.setCreateTime(now);
        rat.insert();
        logger.info("新增风险管理" + rmt.getBaseID() + "由" + userTable.getLinkdoodID() + "-" + userTable.getLinkdoodName() + "新增");
        pushTemplateMessage(rmt, rmt.getApprovalUserID(), riskTypeTableMapper.selectById(rmt.getPrimaryRiskType()).getName());
        return renderSuccess();
    }

    @Override
    public JSONResult getListRiskManage(Page<RiskManageTable> page, String startTime, String endTime, String warningLevel, String riskLevel, Integer timeType, Integer status, String title) {
        UserTable userTable = (UserTable) HttpContextUtils.getHttpServletRequest().getSession().getAttribute("user");
        EntityWrapper<RiskManageTable> ew = new EntityWrapper<>();
        if (status != null) {
            if (status == 1) {
                ew.and("status!=7");
                ew.orderBy("approvalUserID != " + userTable.getLinkdoodID() + ",updateTime", false);
            } else if (status == 2) {
                ew.eq("status", 7);
                ew.orderBy("updateTime", false);
            }
        }
        if (timeType!=null){
            String timeTypeString = timeType==1?"createTime":"updateTime";
            if (StringUtils.isNotEmpty(startTime)&&StringUtils.isNotEmpty(endTime)){
                ew.between(timeTypeString,startTime+" 00:00:00",endTime+" 23:59:59");
            }else if (StringUtils.isNotEmpty(startTime)&&StringUtils.isEmpty(endTime)){
                ew.and(timeTypeString+">={0}",startTime);
            }else if (StringUtils.isEmpty(startTime)&&StringUtils.isNotEmpty(endTime)){
                ew.and(timeTypeString+"<={0}",endTime);
            }
        }
        if (StringUtils.isNotEmpty(title)) {
            ew.like("title", title);
        }
        if (StringUtils.isNotEmpty(warningLevel)) {
            ew.in("warningLevel", warningLevel.split(","));
        }
        if (StringUtils.isNotEmpty(riskLevel)) {
            ew.in("primaryRiskGrade", riskLevel.split(","));
        }
        ew.and("(createUserID = {0} or approvalUserID = {0} or baseID in (select baseID from RISK_APPROVAL_TABLE where userID = {0}))", userTable.getLinkdoodID());
        List<RiskManageTable> rmts = riskManageTableMapper.selectPage(page, ew);
        for (RiskManageTable rmt : rmts) {
            rmt.setCreateUserInfo(userTableMapper.selectById(rmt.getCreateUserID()));
            rmt.setApprovalUserInfo(userTableMapper.selectById(rmt.getApprovalUserID()));
            rmt.setRiskType(riskTypeTableMapper.selectById(rmt.getPrimaryRiskType()));
        }
        page.setRecords(rmts);
        return renderSuccess(page);
    }

    @Override
    public JSONResult getRiskManage(Integer id) {
        RiskManageTable rmt = getRiskExtend(id);
        if (rmt == null) {
            return renderError("信息不存在！");
        }
        return renderSuccess(rmt);
    }

    @Override
    public RiskManageTable getRiskExtend(Integer id) {
        RiskManageTable rmt = riskManageTableMapper.selectById(id);
        if (rmt != null) {
            rmt.setCreateUserInfo(userTableMapper.selectById(rmt.getCreateUserID()));
            rmt.setApprovalUserInfo(userTableMapper.selectById(rmt.getApprovalUserID()));
            String[] appendixAttIDs = StringUtils.isNotEmpty(rmt.getAppendix()) ? rmt.getAppendix().split(",") : new String[0];
            List<AttachmentTable> appendixAttList = new ArrayList<>();
            for (String appendixAttID : appendixAttIDs) {
                appendixAttList.add(attachmentTableMapper.selectById(appendixAttID));
            }
            rmt.setAppendixList(appendixAttList);
            String[] attIDs = StringUtils.isNotEmpty(rmt.getEnclosure()) ? rmt.getEnclosure().split(",") : new String[0];
            List<AttachmentTable> attachmentList = new ArrayList<>();
            for (String attID : attIDs) {
                attachmentList.add(attachmentTableMapper.selectById(attID));
            }
            rmt.setAttachmentList(attachmentList);
            RiskTypeTable riskType = riskTypeTableMapper.selectById(rmt.getPrimaryRiskType());
            rmt.setRiskType(riskType);
            List<IndustryTable> industryList = industryTableMapper.selectList(new EntityWrapper<IndustryTable>().in("id", rmt.getIndustryIDs().split(",")));
            if (CollectionUtils.isNotEmpty(industryList)) {
                List<String> industryListString = new ArrayList<>();
                for (IndustryTable it : industryList) {
                    industryListString.add(it.getName());
                }
                rmt.setIndustryListString(StringUtils.join(industryListString, ","));
            }
            rmt.setIndustryList(industryList);
            List<RegionTable> regionList = regionTableMapper.selectList(new EntityWrapper<RegionTable>().in("id", rmt.getRegionIDs().split(",")));
            if (CollectionUtils.isNotEmpty(regionList)) {
                List<String> regionListString = new ArrayList<>();
                for (RegionTable rrt : regionList) {
                    regionListString.add(rrt.getName());
                }
                rmt.setRegionListString(StringUtils.join(regionListString, ","));
            }
            rmt.setRegionList(regionList);
            if (StringUtils.isNotEmpty(rmt.getInfrastructureIDs())) {
                List<InfrastructureInformationTable> iits = new ArrayList<>();
                for (String InfrastructureInformationID : rmt.getInfrastructureIDs().split(",")) {
                    InfrastructureInformationTable iit = infrastructureInformationTableMapper.selectById(InfrastructureInformationID);
                    iits.add(iit);
                }
                rmt.setInfrastructureList(iits);
            }
            List<RiskApprovalTable> riskApprovalList = riskApprovalTableMapper.selectList(new EntityWrapper<RiskApprovalTable>().eq("baseID", id));
            for (RiskApprovalTable rat : riskApprovalList) {
                rat.setUserInfo(userTableMapper.selectById(rat.getUserID()));
            }
            rmt.setApprovalList(riskApprovalList);
            getFeedbackNum(rmt, rmt.getDownsSet());
            getManufacturers(rmt, rmt.getManufacturers());
        }
        return rmt;
    }

    @Override
    public JSONResult releaseRisk(RiskManageTable rmt) {
        try {
            List<String> orgIDs = JSONArray.parseArray(rmt.getDownsSet(), String.class);
            List<String> safeOrgIDS = JSONArray.parseArray(rmt.getManufacturers(), String.class);
            //1.根据OrgID查询组织下的人员
            List<String> all = orgIDs;
            if (!org.springframework.util.CollectionUtils.isEmpty(safeOrgIDS))
                all.addAll(safeOrgIDS);
            List<UserTable> list = userTableMapper.selectList(new EntityWrapper<UserTable>().in("orgID", all));
            //2.创建反馈表
            RiskFeedbackTable riskFeedback = new RiskFeedbackTable();
            riskFeedback.setBaseID(rmt.getBaseID());
            riskFeedback.setCreateTime(new Date());
            for (String orgid : all) {
                riskFeedback.setOrgID(orgid);
                riskFeedbackTableMapper.insert(riskFeedback.clone());
            }
            //4.记录下发厂商/应对要求/处置要求
            rmt.setReplyClaim(rmt.getReplyClaim());//应对要求
            rmt.setHandleClaim(rmt.getHandleClaim());//处置要求
            rmt.setManufacturers(rmt.getManufacturers());//下发的安全厂商
            //5.记录下发单位
            rmt.setDownsSet(rmt.getDownsSet());
            riskManageTableMapper.updateById(rmt);
            // TODO: 2018/1/16
            riskApprovalTableService.releaseRiskApproval(rmt.getBaseID(), "值班员下发");
            //6.推送模板消息
            Set<String> toUsers = new HashSet<>();
            for (UserTable u : list) {
                toUsers.add(u.getLinkdoodID());
            }
            pushTemplateMessage(rmt, new ArrayList<>(toUsers));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return renderSuccess();
    }

    @Override
    public JSONResult getListProfessorRisk(Page<RiskManageTable> page, Integer status) {
        UserTable userTable = (UserTable) HttpContextUtils.getHttpServletRequest().getSession().getAttribute("user");
        if (!roleTableMapper.selectById(userTable.getRoleID()).getRoleRank().equals("6")) {
            return renderError("操作被禁止，当前用户不是专家！");
        }
        EntityWrapper<RiskManageTable> ew = new EntityWrapper<>();
        if (status == 0) {
            ew.and("status!=7");
            ew.and("approvalUserID = {0}", userTable.getLinkdoodID());
        }
        if (status == 1) {
            ew.and("status!=7");
            ew.and("baseID in (select baseID from RISK_APPROVAL_TABLE where userID = {0})", userTable.getLinkdoodID());
            ew.and("approvalUserID != {0}", userTable.getLinkdoodID());
        }
        if (status == 2) {
            ew.and("baseID in (select baseID from RISK_APPROVAL_TABLE where userID = {0})", userTable.getLinkdoodID());
            ew.eq("status", 7);
        }
        ew.orderBy("updateTime", false);
        List<RiskManageTable> rmts = riskManageTableMapper.selectPage(page, ew);
        for (RiskManageTable rmt : rmts) {
            rmt.setCreateUserInfo(userTableMapper.selectById(rmt.getCreateUserID()));
            rmt.setApprovalUserInfo(userTableMapper.selectById(rmt.getApprovalUserID()));
            rmt.setRiskType(riskTypeTableMapper.selectById(rmt.getPrimaryRiskType()));
        }
        page.setRecords(rmts);
        return renderSuccess(page);
    }

    private void getFeedbackNum(RiskManageTable rmt, String downSet) {
        //4.共下发多少家,反馈/未反馈数据量
        List<String> list = JSON.parseArray(downSet, String.class);
        if (list != null && list.size() > 0) {
            rmt.setTotalNum(list.size());
            rmt.setFeedbackNum(riskFeedbackTableMapper.selectCount(new EntityWrapper<RiskFeedbackTable>()
                    .eq("baseID", rmt.getBaseID())
                    .in("orgID", list)
                    .in("status", new Integer[]{1, 2})));
        }
    }

    private void getManufacturers(RiskManageTable rmt, String manufacturers) {
        //5.安全厂商共下发了多少家, 反馈/未反馈数据量
        List<String> list = JSON.parseArray(manufacturers, String.class);
        if (list != null && list.size() > 0) {
            rmt.setTotalManuf(list.size());
            rmt.setHadSubmit(riskFeedbackTableMapper.selectCount(new EntityWrapper<RiskFeedbackTable>()
                    .eq("baseID", rmt.getBaseID())
                    .in("orgID", list)
                    .in("status", new Integer[]{1, 2})));
        }
    }

    private void pushTemplateMessage(RiskManageTable rmt, String toUsers, String type) {
        String appid = apiV2Service.getAppID();
        String content = "时间: " + dateFormat.format(new Date()) + "\n标题：" + rmt.getTitle() + "\n类别: " + type + "\n请您及时处理 ";
        TemplateMessage templateMessage = TemplateMessage.createOne(appid, "风险管理", appid, content, wxbSystemConfig.getRiskFeedbackDetailUrl() + "&id=" + rmt.getBaseID(),
                toUsers);
        try {
            executorService.execute(new DDIORunnable(apiV2Service, "sendTemplateMsg", templateMessage, TemplateMessage.class));
        } catch (NoSuchMethodException e) {
            logger.info("推送风险管理" + "(ID" + rmt.getBaseID() + ")消息失败! ");
            e.printStackTrace();
        }
    }

    private void pushTemplateMessage(RiskManageTable rmt, List<String> toUsers) {
        String appid = apiV2Service.getAppID();
        rmt = riskManageTableMapper.selectById(rmt.getBaseID());
        RiskTypeTable riskType = riskTypeTableMapper.selectById(rmt.getPrimaryRiskType());
        String content = "时间: " + dateFormat.format(new Date()) + "\n标题：" + rmt.getTitle() + "\n类别: " + riskType.getName() + "\n请您及时处理 ";
        TemplateMessage templateMessage = TemplateMessage.createOne(appid, "风险管理", appid, content, wxbSystemConfig.getRiskFeedbackDetailUrl() + "&id=" + rmt.getBaseID(),
                StringUtils.join(toUsers.toArray(), ','));
        try {
            executorService.execute(new DDIORunnable(apiV2Service, "sendTemplateMsg", templateMessage, TemplateMessage.class));
        } catch (NoSuchMethodException e) {
            logger.info("推送事件管理(ID" + rmt.getBaseID() + ")消息失败! ");
            e.printStackTrace();
        }
    }
}
